package com.gitee.wsl.collections.set

import androidx.collection.IntSet
import androidx.collection.MutableIntSet
import com.gitee.wsl.ext.base.Arrays
//
//class IntSet(size: Int = 16): Iterable<Int>, Comparable<IntSet> {
//
//    private var elements = IntArray(size)
//
//    var size: Int = 0
//        private set
//
//    val first: Int get() = elements[0]
//
//    val last: Int get() = elements[size - 1]
//
//    operator fun get(index: Int): Int {
//        return elements[index]
//    }
//
//    fun add(item: Int): Boolean {
//        val index = elements.indexOf(item)
//        //val index = Arrays.binarySearch(elements, 0, size, item)
//        if (index >= 0) {
//            // it exists.
//            return false
//        }
//
//        ensureSize(size + 1)
//
//        // index == (-(insertion point) - 1)
//        val insertionPoint = -(index + 1)
//
//        // move all by one behind.
//        Arrays.arraycopy(
//            elements,
//            insertionPoint,
//            elements,
//            insertionPoint + 1,
//            size - insertionPoint
//        )
//        //elements.copyInto(elements,insertionPoint + 1, insertionPoint,size )
//        elements[insertionPoint] = item
//        size++
//        return true
//    }
//
//    private fun ensureSize(requiredSize: Int) {
//        if (elements.size < requiredSize) {
//            var newSize = elements.size
//            while (newSize < requiredSize) {
//                newSize *= 2
//            }
//            val newElements = IntArray(newSize)
//            Arrays.arraycopy(elements, 0, newElements, 0, elements.size)
//            //elements.copyInto(newElements,0,newSize,)
//            elements = newElements
//        }
//    }
//
//    val isEmpty: Boolean
//        get() = size == 0
//
//    fun addAll(other: IntSet) {
//        for (i in 0 until other.size) {
//            add(other[i])
//        }
//    }
//
//    fun addAll(other: IntArray) {
//        for (element in other) {
//            add(element)
//        }
//    }
//
//    operator fun contains(item: Int): Boolean {
//        //return Arrays.binarySearch(elements, 0, size, item) >= 0
//        return elements.indexOf(item) >= 0
//    }
//
//    fun retainAll(other: IntSet) {
//        for (i in size - 1 downTo 0) {
//            if (!other.contains(get(i))) {
//                removeAt(i)
//            }
//        }
//    }
//
//    fun removeAll(other: IntSet) {
//        for (i in 0 until other.size) {
//            remove(other[i])
//        }
//    }
//
//    fun remove(item: Int): Boolean {
//        val index = elements.indexOf(item)
//        if (index < 0) {
//            return false
//        }
//        removeAt(index)
//        return true
//    }
//
//    private fun removeAt(index: Int) {
//        Arrays.arraycopy(elements, index + 1, elements, index, size - 1 - index)
//        size--
//    }
//
//    fun containsAny(other: IntSet): Boolean {
//        var i0 = 0
//        var i1 = 0
//        while (i0 < size && i1 < other.size) {
//            when {
//                get(i0) < other[i1] -> {
//                    i0++
//                }
//                get(i0) > other[i1] -> {
//                    i1++
//                }
//                else -> {
//                    return true
//                }
//            }
//        }
//        return false
//    }
//
//    fun indexOfFirstMatch(other: IntSet): Int {
//        var i0 = 0
//        var i1 = 0
//
//        while (i0 < size && i1 < other.size) {
//            when {
//                get(i0) < other[i1] -> i0++
//                get(i0) > other[i1] -> i1++
//                else -> return i0
//            }
//        }
//
//        return -1
//    }
//
//
//    fun clear() {
//        size = 0
//    }
//
//    override fun compareTo(other: IntSet): Int {
//        repeat(kotlin.math.min(size, other.size)) {
//            val cmp = elements[it].compareTo(other.elements[it])
//
//            if(cmp != 0) {
//                return cmp
//            }
//        }
//
//        return size.compareTo(other.size)
//    }
//
//    override fun toString(): String {
//        return "{${this.joinToString(", ")}}"
//    }
//
//
//    override fun iterator(): Iterator<Int> {
//        return object: Iterator<Int>{
//            var index = 0
//
//            override fun hasNext(): Boolean {
//                return index < size
//            }
//
//            override fun next(): Int {
//                return this@IntSet[index++]
//            }
//        }
//    }
//
//    fun merge(array: IntArray) {
//        var i = 0
//        val n: Int = array.size
//        while (i < n) {
//            val value: Int = array[i]
//            if (indexOf(value) < 0) {
//                add(value)
//            }
//            i++
//        }
//
//    }
//
//    fun merge(value: Int){
//        if (!contains(value)) add(value)
//    }
//
//}


/**
 * Returns an empty, read-only [IntSet].
 */
fun Sets.emptyIntSet(): IntSet = androidx.collection.emptyIntSet()

/**
 * Returns an empty, read-only [ScatterSet].
 */
@Suppress("UNCHECKED_CAST")
fun Sets.intSetOf(): IntSet = androidx.collection.intSetOf()

/**
 * Returns a new read-only [IntSet] with only [element1] in it.
 */
@Suppress("UNCHECKED_CAST")
fun Sets.intSetOf(element1: Int): IntSet = mutableIntSetOf(element1)

/**
 * Returns a new read-only [IntSet] with only [element1] and [element2] in it.
 */
@Suppress("UNCHECKED_CAST")
fun Sets.intSetOf(element1: Int, element2: Int): IntSet =
    mutableIntSetOf(element1, element2)

/**
 * Returns a new read-only [IntSet] with only [element1], [element2], and [element3] in it.
 */
@Suppress("UNCHECKED_CAST")
fun Sets.intSetOf(element1: Int, element2: Int, element3: Int): IntSet =
    mutableIntSetOf(element1, element2, element3)

/**
 * Returns a new read-only [IntSet] with only [elements] in it.
 */
@Suppress("UNCHECKED_CAST")
fun Sets.intSetOf(vararg elements: Int): IntSet =
    MutableIntSet(elements.size).apply { plusAssign(elements) }

/**
 * Returns a new [MutableIntSet].
 */
fun Sets.mutableIntSetOf(): MutableIntSet = MutableIntSet()

/**
 * Returns a new [MutableIntSet] with only [element1] in it.
 */
fun Sets.mutableIntSetOf(element1: Int): MutableIntSet =
    MutableIntSet(1).apply {
        plusAssign(element1)
    }

/**
 * Returns a new [MutableIntSet] with only [element1] and [element2] in it.
 */
fun Sets.mutableIntSetOf(element1: Int, element2: Int): MutableIntSet =
    MutableIntSet(2).apply {
        plusAssign(element1)
        plusAssign(element2)
    }

/**
 * Returns a new [MutableIntSet] with only [element1], [element2], and [element3] in it.
 */
fun Sets.mutableIntSetOf(element1: Int, element2: Int, element3: Int): MutableIntSet =
    MutableIntSet(3).apply {
        plusAssign(element1)
        plusAssign(element2)
        plusAssign(element3)
    }

/**
 * Returns a new [MutableIntSet] with the specified elements.
 */
fun Sets.mutableIntSetOf(vararg elements: Int): MutableIntSet =
    MutableIntSet(elements.size).apply { plusAssign(elements) }
